package com.tqjc.business.interactivewithscan.core.thread;

import com.alibaba.fastjson.JSONObject;
import com.tqjc.business.interactivewithscan.core.data.AskData.AskData;
import com.tqjc.business.interactivewithscan.core.data.PointData.PointData;
import com.tqjc.business.interactivewithscan.core.operation.SpecificOperation;
import com.tqjc.business.interactivewithscan.entity.DeviceSocketClient;
import com.tqjc.business.interactivewithscan.entity.ScanDeviceData;
import com.tqjc.business.interactivewithscan.entity.UfcDeviceInfo;
import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * @program: C20005_Xianggang_new
 * @description: 线程基类
 * @author: Patienyon
 * @create: 2023-11-01 18:08
 **/

@Slf4j
public class NormalThread extends Thread{
    @Getter
    protected JSONObject data = new JSONObject();

    @Getter
    protected ScanDeviceData device;
    @Getter
    protected UfcDeviceInfo deviceInfo;
    @Getter
    protected DeviceSocketClient socketClient;

    @Getter
    @Setter
    public volatile Queue<AskData> askDataQue = new LinkedBlockingQueue<>();

    @Getter
    @Setter
    public volatile Map<String, PointData> responseMap = new LinkedHashMap<>();

    private ArrayBlockingQueue queue = new ArrayBlockingQueue<Boolean>(1);

    public void setDevice(ScanDeviceData device, UfcDeviceInfo deviceInfo) {
        this.device = device;
        this.deviceInfo = deviceInfo;
    }

    @Override
    public void run() {
    }

    public void checkSocket() {

            if (socketClient == null) {
                socketClient = new DeviceSocketClient(device, queue);
            }
        synchronized (socketClient) {
            if (!socketClient.succeeded()) {
                do {
                    int err = 0;
                    try {
                        VertxOptions options = new VertxOptions();
                        options.setWorkerPoolSize(40);
                        Vertx.vertx(options).deployVerticle(socketClient);
                        boolean take = (boolean) queue.take();
                        if (take) {
                            err = 0;
                            heartbeat(socketClient);
                            break;
                        } else {
                            err++;
                            if (err == 1) {
                                log.error("设备：【" + device.getDeviceName() + "】连接失败！");
                            }
                            socketClient.stop();
                        }
                    } catch (Exception e) {
                        err++;
                        if (err == 1) {
                            log.error("【" + device.getDeviceName() + "】socket连接错误！");
                        }
                        try {
                            socketClient.stop();
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    }
                } while (true);
            }
        }
//        }else{
//            heartbeat(socketClient);
//        }
    }

    /**
     * 心跳检测
     *
     * @param socketClient
     */
    public void heartbeat(DeviceSocketClient socketClient) {

    }

    /**
     * 除了设备信息，socket信其他的都清除
     */
    public void cleanData() {
        data.clear();
    }

    public void operation(List<SpecificOperation> operations) {
        for (int i = 0; i < operations.size(); ) {
            try {
                //校验socket
                checkSocket();
                operations.get(i).setDevice(device, deviceInfo, socketClient);
                boolean operation = operations.get(i).operation(i);
                //动作执行失败，上一个动作出现执行结果异常，重新执行
                if (!operation) {
                    if (i != 0) {
                        i--;
                    }
                }
                //已经是最后一个动作执行完成
                else {
                    if (i == operations.size() - 1) {
                        //除了设备信息，socket信其他的都清除
                        cleanData();
                        //从第一个动作重开始执行
                        i = 0;
                    } else {
                        i++;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                break;
            }
        }
    }

}
